package cn.qfei.qiyuesuo.common.until;

import cn.qfei.qiyuesuo.vo.qiyuesuo.CallbackData;
import cn.qfei.qiyuesuo.vo.qiyuesuo.CallbackValidateResult;
import org.springframework.util.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;

public class QiyuesuoCallbackUtils {
	
	private final String aesKey;
	private final String token;
	
	public QiyuesuoCallbackUtils(String aesKey, String token) {
		this.aesKey = aesKey;
		this.token = token;
	}
	
	/**
	 * 回调校验
	 */
	public CallbackValidateResult callbackValidateResult(CallbackData callbackData) {
		String encrypted = callbackData.getEncrypted();
		String plainText;
		try {
			plainText = decrypt(encrypted);
		} catch (Exception e) {
			CallbackValidateResult result = new CallbackValidateResult(false, "解密失败", null, callbackData);
			result.setException(e);
			return result;
		}
		Long timestamp = callbackData.getTimestamp();
		String nonce = callbackData.getNonce();
		String signature = callbackData.getSignature();
		String compSignature = toMD5(plainText + timestamp + nonce + token);
		if (!compSignature.equals(signature)) {
			return new CallbackValidateResult(false, "签名校验失败", plainText, callbackData);
		}
		return new CallbackValidateResult(true, null, plainText, callbackData);
	}
	
	/**
	 * 回调原文解密
	 */
	public String decrypt(String encryptedText) throws Exception {
		byte[] keyBytes = aesKey.getBytes(StandardCharsets.UTF_8);
		SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, 0, 16, "AES");
		
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		byte[] ivBytes = getHashBytes(token);
		IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes, 0, 16);
		cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
		
		byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
		
		byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
		
		return new String(decryptedBytes, StandardCharsets.UTF_8);
	}
	
	private byte[] getHashBytes(String source) throws Exception {
		MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
		return messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));
	}
	
	private String toMD5(String text) {
		byte[] textByte = text.getBytes(StandardCharsets.UTF_8);
		return DigestUtils.md5DigestAsHex(textByte);
	}
	
}
